﻿// 64 位输出请用 printf("%lld")



//链接：https://ac.nowcoder.com/acm/problem/229023
//来源：牛客网
//
//dd当上了宣传委员，开始组织迎新晚会，已知班里有
//�
//n个同学，每个同学有且仅有一个擅长的声部，把同学们分成恰好
//�
//m组，为了不搞砸节目，每一组里的同学都必须擅长同一个声部，当然，不同组同学擅长同一个声部的情况是可以出现的，
//毕竟一个声部也可以分成好几个part进行表演，但是他不希望出现任何一组的人过多，否则可能会导致场地分配不协调
//，也就是说，她希望人数最多的小组的人尽可能少，除此之外，对组内人员分配没有其他要求，她希望你告诉她，这个值是多少，
//如果无法顺利安排，请输出 - 1
//输入描述:
//第一行两个数个数n, m(1≤m≤n≤100000)表示人数
//接下来一行n个数, a[i](1≤a[i]≤n)表示第i个学生的擅长声部
//输出描述 :
//输出一个数，表示人数最多的小组的人数
//示例1
//输入
//复制
//5 3
//2 2 3 3 3
//输出
//复制
//2



//思路：逆向回推试探法：就是拿着结果所在的区间范围一个个去试探；
//条件1.不同声部的人不能在同一组
//条件2.所分组的最大人数的小组的人数为x，要求x最小

//根据条件1我们可以利用hash把同一声部的人放一起，这样得到了所分组的组数的最小值，如果m比它小，则不成立
//而根据hash还可以得到某声部人数最多的是多少人，这样也就决定了我们后面去试探这个x的范围了->[1,max]
//然后我们先假设分x个一组，因为它要的是最小故x从1开始遍历去试探；（要知道我们最多的那个max一定
//分组会的组中含有x个人），因此试探的过程把m总加起来 应该是 >m =m <m ,一个过程，（我们要选择的是
//让它成立的x的最小值）；遇到等于m就直接返回它，遇到<m(相当于我们还可以把其他不满x的再分多组，使它满足
//总共m组，那么<m也就可以返回了)
#include<iostream>
#include<vector>
#include<algorithm>
#include<unordered_map>
using namespace std;
unordered_map<int, int> hc;
int n, m;
int check(int t) {
    int sum = 0;
    for (auto [a, b] : hc) {
        sum += b / t + (b % t == 0 ? 0 : 1);
    }
    return sum <= m ? t : 0;
}
int main() {
    cin >> n >> m;
    vector<int> v(n);
    int maxcount = 0;
    //放入hash+得到声部最多的人数的人：
    for (int i = 0; i < n; i++) {
        cin >> v[i];

        maxcount = max(++hc[v[i]], maxcount);
    }
    //判断是否要分的组m过小：
    if (m < hc.size()) cout << -1 << endl;

    else {
        int l = 1, r = maxcount;
        while (l < r) {
            int mid = (l + r) / 2;
            if (check(mid)) r = mid;
            else l = mid + 1;
        }
        cout << l << endl;


    }
    return 0;
}
